package com.xc.pay.weixin.template.Base;

import cn.hutool.json.JSONObject;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.xc.pay.weixin.util.CertUtil;
import org.apache.http.client.HttpClient;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Collections;

/**
 * 构造Client对象
 *
 * @author: rongrong
 * @version: 1.0
 * @time: 2020-11-28 17:14
 */
public interface WxPayTemplate {

  /**
   * 初始化CloseableHttpClient 自动签名验签
   * 方法参照微信官方https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient
   *
   * @return org.apache.http.impl.client.CloseableHttpClient
   */
  default JSONObject initApiV3HttpClient(
      String privateKeyPath,
      String privateCertPath,
      String certSerialNumber,
      String apiV3Key,
      String mchid) {
    // 读取证书文件
    InputStream keyInputStream = CertUtil.loadConfigInputStream(privateKeyPath);
    InputStream certInputStream = CertUtil.loadConfigInputStream(privateCertPath);
    try {
      PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(keyInputStream);
      X509Certificate certificate = PemUtil.loadCertificate(certInputStream);
      // 构建自动更新证书
      final WechatPay2Credentials credentials =
          new WechatPay2Credentials(
              mchid, new PrivateKeySigner(certSerialNumber, merchantPrivateKey));
      AutoUpdateCertificatesVerifier verifier =
          new AutoUpdateCertificatesVerifier(
              credentials,
              apiV3Key.getBytes(StandardCharsets.UTF_8),
              AutoUpdateCertificatesVerifier.TimeInterval.OneHour.getMinutes());
      // 构建请求对象
      final HttpClient client =
          WechatPayHttpClientBuilder.create()
              .withMerchant(mchid, certSerialNumber, merchantPrivateKey)
              .withWechatpay(Collections.singletonList(certificate))
              .withValidator(new WechatPay2Validator(verifier))
              .build();
      final JSONObject object = new JSONObject();
      object
          .putOpt("httpClient", client)
          .putOpt("credentials", credentials)
          .putOpt("privateKey", merchantPrivateKey);
      return object;
    } catch (Exception e) {
      throw new RuntimeException("v3请求构造异常！", e);
    }
  }
}
